﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using VoteSystem.Models;

namespace VoteSystem.Services
{
    public class AccountService
    {
        public OpResult Login(LoginModel model)
        {
            OpResult result = new OpResult();
            result.ErrorMessage = "抱歉,登录失败,请联系管理员!";
            result.IsSuccess = false;
            HttpContext.Current.Application.Lock();
            if (HasLogin(model.UserName)) 
            {
                result.ErrorMessage = "抱歉,您的账号已经登录，不能重复登录";
                HttpContext.Current.Application.UnLock();
                return result;
            }
            try
            {
                using (VoteSystemContext db = new VoteSystemContext())
                {
                   string hashpwd = Md5(model.Password);
                   var user = db.UserProfiles.FirstOrDefault(u => u.UserName == model.UserName && u.Password == hashpwd);
                   if (user != null)
                   {
                       UserInSession usession = new UserInSession(user.UserId, user.DisplayName, user.Role.RoleId, user.Role.RoleName, user.DeptName, user.UserName);
                       HttpContext.Current.Session["loginUser"] = usession;
                       result.IsSuccess = true;
                       result.ErrorMessage = string.Empty;
                       LoginPersist(model.UserName);
                   }
                   else 
                   {
                       result.ErrorMessage = "抱歉,账号或者密码错误！";
                   }
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex.Message);
                LogHelper.Error(ex.StackTrace);
            }
            HttpContext.Current.Application.UnLock();
            return result;
        }


        public string Md5(string input)
        {
            string cl = input;
            string pwd = "";
            MD5 md5 = MD5.Create(); //实例化一个md5对像
            // 加密后是一个字节类型的数组，这里要注意编码UTF8/Unicode等的选择　
            byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl));
            // 通过使用循环，将字节类型的数组转换为字符串，此字符串是常规字符格式化所得
            for (int i = 0; i < s.Length; i++)
            {
                // 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母，如果使用大写（X）则格式后的字符是大写字符 
                pwd = pwd + s[i].ToString("X");
            }
            return pwd;
        }


        public OpResult ChangePassword(string oldPassword, string newPassword) 
        {
            OpResult result = new OpResult();
            try
            {
                System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(@"[!@#$%^&*]{1,}");
                if (!reg.IsMatch(newPassword))
                {
                    result.ErrorMessage = "密码必须包含特殊字符：!@#$%^&*()-= 其中之一";
                    return result;
                }
                UserInSession userInSession = (UserInSession)HttpContext.Current.Session["loginUser"];

                using (VoteSystemContext db = new VoteSystemContext())
                {
                    var user = db.UserProfiles.Find(userInSession.UserId);

                    string old = Md5(oldPassword);
                    if (user.Password == old)
                    {
                        user.Password = Md5(newPassword);

                        db.SaveChanges();
                        result.IsSuccess = true;
                    }
                    else 
                    {
                        result.IsSuccess = false;
                        result.ErrorMessage = "原始密码错误！";
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex.Message);
                LogHelper.Error(ex.StackTrace);
                result.ErrorMessage = "系统错误！";
            }
            return result;
        }

        /// <summary>  
        /// 获取客户端IP地址  
        /// </summary>  
        /// <returns></returns>  
        public  string GetIP()
        {
            string result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            if (string.IsNullOrEmpty(result))
            {
                result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            }
            if (string.IsNullOrEmpty(result))
            {
                result = HttpContext.Current.Request.UserHostAddress;
            }
            if (string.IsNullOrEmpty(result))
            {
                return "0.0.0.0";
            }
            return result;
        }

        public bool HasLogin(string userName)
        {
            if (userName == "admin") return false;
            bool hasLogin = false;
            if (HttpContext.Current.Application[userName] != null) hasLogin = true;
            return hasLogin;
        }

        public void LoginPersist(string userName) 
        {
            if(userName != "admin")
                 HttpContext.Current.Application[userName] = userName;
        }

        public void LoginOff(string userName) 
        {
            HttpContext.Current.Application.Lock();
            if (HttpContext.Current.Application.AllKeys.Contains(userName)) 
            {
                HttpContext.Current.Application.Remove(userName);
            }
            HttpContext.Current.Application.UnLock();
        }
    }
}